home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / pmode / exc_dx02 / exc_1.c < prev    next >
C/C++ Source or Header  |  1994-10-25  |  5KB  |  189 lines

  1.  
  2. #include <stdio.h>
  3. #include <process.h>
  4. #include <pharlap.h>
  5. #include "exc.h"
  6. #include "uasm.h"
  7.  
  8. #define MAX_EX           17
  9. #define HOOK_BREAK_POINT  1
  10.  
  11. /*
  12.  * Prototypes
  13.  */
  14.  
  15. static void HookExcHandler (char i, unsigned int cs);
  16. static char errCodeExc     (char i);
  17. static char *errCodeStr    (char i,short x);
  18. static void LocalHook      (void);
  19.  
  20. /*
  21.  * Public data
  22.  */
  23.  
  24. FARPTR oldExcHandlers [MAX_EX+1];
  25.  
  26. /*
  27.  * Local data
  28.  */
  29.  
  30. static void (* excHookUser)(excReg *r);
  31. static char uasmAtExc;
  32. static char privLevel;
  33.  
  34. /*
  35.  *  Application interface to exception handler system
  36.  *  Called once during main start. Add/remove handlers as
  37.  *  required. Can be invoked multiple times
  38.  */
  39.  
  40. void InstallExcHandler (void (*userHook)(excReg *r), char debugDump)
  41. {
  42.   int          i;
  43.   unsigned int cseg;
  44.   CONFIG_INF   cnf;
  45.  
  46.   _dx_config_inf(&cnf,(char*)&cnf);  /* get config block */
  47.   cseg = cnf.c_cs_sel;
  48.   privLevel = cseg & ~3;
  49.  
  50.   /* Save vectors for all exception handlers  */
  51.  
  52.   for (i=0; i<MAX_EX; i++)
  53.      _dx_excep_get(i,&oldExcHandlers[i]);
  54.  
  55. #if 1         // normally #if 0 is sufficient
  56.   HookExcHandler( 0,cseg);   /* divide error exception   */
  57.   HookExcHandler( 3,cseg);   /* break point exception    */
  58.   HookExcHandler( 4,cseg);   /* integer overflow exc     */
  59.   HookExcHandler( 5,cseg);   /* array bound exception    */
  60.   HookExcHandler( 6,cseg);   /* Illegal opcode exception */
  61.   HookExcHandler( 7,cseg);   /* Coprocessor not present  */
  62.   HookExcHandler(11,cseg);   /* segment not present exc  */
  63.   HookExcHandler(12,cseg);   /* stack fault exception    */
  64. #endif
  65.   HookExcHandler(13,cseg);   /* general protection exc   */
  66.   HookExcHandler(14,cseg);   /* page fault exception     */
  67.  
  68.   excHookUser = userHook;
  69.   excHookMain = &LocalHook;
  70.   uasmAtExc   = debugDump;
  71. }
  72.  
  73. /*
  74.  *  Should be called by application before exit();
  75.  *  Although not strictly necessary.
  76.  *
  77.  */
  78.  
  79. void RemoveExcHandler (void)
  80. {
  81.   int i;
  82.  
  83.   /* Restore all exception vectors */
  84.  
  85.   for (i=0; i<MAX_EX; i++)
  86.      _dx_excep_set(i,oldExcHandlers[i]);
  87. }
  88.  
  89. /*-----------------------------------------------------------------*/
  90.  
  91. static char errCodeExc(char i)
  92. {
  93.   return (i == 8 || (i>=10 && i<=14));
  94. }
  95.  
  96. /*-----------------------------------------------------------------*/
  97.  
  98. static char * errCodeStr(char i,short x)
  99. {
  100.   static char buf[23];
  101.   if (errCodeExc(i))
  102.   {
  103.     sprintf(buf,"Error code %Xh. ",x);
  104.     return buf;
  105.   }
  106.   else return "";
  107. }
  108.  
  109. /*--------------------------------------------------------------*/
  110.  
  111. void HookExcHandler (char i, unsigned int cs)
  112. {
  113.   FARPTR newExcHandler;
  114.  
  115. #if HOOK_BREAK_POINT == 0
  116.   if (i == 3) return;
  117. #endif
  118.  
  119.   if (errCodeExc(i))
  120.   {
  121.     FP_SET(newExcHandler,&ExcGlue_1,cs);
  122.   }
  123.   else
  124.   {
  125.     FP_SET(newExcHandler,&ExcGlue_0,cs);
  126.   }
  127.   _dx_excep_set(i,newExcHandler);
  128. }
  129.  
  130. /*-----------------------------------------------------------------*/
  131.  
  132. static void LocalHook(void)
  133. {
  134.   int i;
  135.   static excReg *r = &except;
  136.   static void *adr;
  137.   static char *excName[] = { "Divide Exception",      // 0
  138.                              "Debug Exception",
  139.                              "NMI !!??",              // 2
  140.                              "Breakpoint",
  141.                              "Overflow",              // 4
  142.                              "Array Bound Check",
  143.                              "Invalid Opcode",        // 6
  144.                              "FPU not present",
  145.                              "Double Fault",          // 8
  146.                              "FPU Segment Overrun",
  147.                              "Invalid TSS",           // 10
  148.                              "Segment not present",
  149.                              "Stack Fault",           // 12
  150.                              "General Protection",
  151.                              "Page Fault",            // 14
  152.                              "FPU Error",
  153.                              "Alignment Check"  };    // 16
  154.  
  155.   RemoveExcHandler();
  156.  
  157.   if (r->number==3 || r->number==4)  /* point to INT 3, INTO  */
  158.      r->EIP -= 1;                    /* INT 3 = CC, INTO = CE */
  159.  
  160.   printf ("%s (exc %d) occured at (CS:EIP) %04X:%08X\n\n"\
  161.           "%sRegisters:\n"                               \
  162.           "EAX %08X  EBX %08X  ECX %08X  EDX %08X\n"     \
  163.           "ESI %08X  EDI %08X  EBP %08X  ESP %08X\n"     \
  164.           "DS  %04X      FS  %04X      SS  %04X\n"       \
  165.           "ES  %04X      GS  %04X      FLG %08X\n",
  166.           excName[r->number],r->number,r->CS,r->EIP,
  167.           errCodeStr(r->number,r->code),
  168.           r->EAX,r->EBX,r->ECX,r->EDX,
  169.           r->ESI,r->EDI,r->EBP,r->ESP,
  170.           r->DS,r->FS,r->SS,r->ES,r->GS,r->EFL);
  171.  
  172.   if (uasmAtExc)
  173.   {
  174.     printf("\nInstruction trace:\n");
  175.     adr = (void*) r->EIP;
  176.     for (i=0; i<8; i++)
  177.     {
  178.       printf("%02X:%08X  %s\n",r->CS,adr,disassemble(adr));
  179.       adr = disasm_outAdr;
  180.     }
  181.  // printf("\nCall Stack:\n");  // whouldn't this be nice :-)
  182.   }
  183.   if (excHookUser != NULL)
  184.     (*excHookUser)(r);
  185.  
  186.   exit((char)r->number);
  187. }
  188.  
  189.